package org.gjy.m8.stream;

import com.google.common.collect.Lists;
import org.gjy.m8.stream.collect.PrimeNumberCollect;
import org.gjy.m8.stream.collect.ToListCollect;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.*;

/**
 * @author 宫静雨
 * @version 1.0
 * @since 2023-10-24 14:45:31
 */
public class DishStreamTest {
    private static final Logger log = LoggerFactory.getLogger(DishStreamTest.class);

    private static final List<Dish> list = Dish.menu;

    @Test
    public void test9() {
        Map<Boolean, List<Integer>> collect = Lists.newArrayList(1, 2, 3, 4, 5, 6)
                .stream()
                .collect(new PrimeNumberCollect());
        System.out.println(collect);
    }

    @Test
    public void test8() {
        List<String> collect = list.stream()
                .map(Dish::getName)
                .collect(new ToListCollect<>());
        System.out.println(collect);
    }

    @Test
    public void test7() {
        Map<Boolean, Map<Dish.Type, List<Dish>>> collect = list.stream()
                .collect(partitioningBy(Dish::getVegetarian, groupingBy(Dish::getType)));
        collect.forEach((k, v) -> log.info("{}={}", k, v));
    }

    @Test
    public void test6() {
        /*Map<Dish.Type, Dish> collect = list.stream()
                .collect(groupingBy(Dish::getType, collectingAndThen(
                        maxBy(Comparator.comparingInt(Dish::getCalories)),
                        Optional::get)));*/
        Map<Dish.Type, Dish> collect = list.stream()
                .collect(toMap(Dish::getType, Function.identity(),
                        BinaryOperator.maxBy(Comparator.comparingInt(Dish::getCalories))));
        collect.forEach((k, v) -> log.info("{}={}", k, v));
    }

    @Test
    public void test5() {
        Lists.newArrayList(1, 2, 3, 4, 5)
                .stream()
                //.reduce(0, Integer::sum);
                .reduce((l, r) -> {
                    log.info("l={}, r={}", l, r);
                    return l + r;
                })
                .ifPresent(System.out::println);
    }

    @Test
    public void test4() {
        Integer reduce = Lists.newArrayList(1, 2, 3, 4, 5)
                .stream()
                //.reduce(0, Integer::sum);
                /*.reduce(0, (l, r) -> {
                    log.info("l={}, r={}", l, r);
                    return l + r;
                });*/
                .reduce(0, Integer::max);
        log.info("{}", reduce);
    }

    @Test
    public void test3() {
        String[] words = {"Hello", "World"};
        String collect = Arrays.stream(words)
                .map(s -> s.split(""))
                .flatMap(Arrays::stream)
                .collect(Collectors.joining(","));
        log.info("{}", collect);
    }

    @Test
    public void test2() {
        long count = list.stream()
                .filter(dish -> dish.getCalories() > 300)
                .count();
        log.info("count: {}", count);
    }

    @Test
    public void test1() {
        list.stream()
                .filter(d -> d.getCalories() > 300)
                .map(Dish::getName)
                .limit(3)
                .collect(Collectors.toList())
                .forEach(System.out::println);
    }

}
